#include "utils/io_utils.hpp"
#include <cassert>

#if defined(_WIN32)
#include <Windows.h>
#include <fmt/format.h>
#elif defined(__unix__)
#include <fcntl.h>
#include <unistd.h>
#else
#error unsupported platform
#endif

std::string ReadTextFile (const std::string &path)
{
    std::string text;
#if defined(_WIN32)
    auto const wpath = fmt::detail::utf8_to_utf16(path);
    HANDLE hFile = CreateFileW(wpath.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hFile != INVALID_HANDLE_VALUE)
    {
        // Get File Length
        LARGE_INTEGER       pos_move{.QuadPart = 0};
        LARGE_INTEGER       pos_ret{.QuadPart = 0};
        if (SetFilePointerEx(hFile, pos_move, &pos_ret, FILE_END))
        {
            text.resize(pos_ret.QuadPart);
            pos_move.QuadPart = 0;
            if (SetFilePointerEx (hFile, pos_move, &pos_ret, FILE_BEGIN))
            {
                DWORD read = 0;
                if (ReadFile(hFile, text.data(), (DWORD)text.size(), &read, NULL))
                {
                    assert(read == text.size());
                }
            }
        }
        CloseHandle(hFile);
    }
#else
    int fd = open(path.c_str(), O_RDONLY);
    if (fd >= 0) {
        // get file length
        const auto length = lseek(fd, 0, SEEK_END);
        text.resize(length);
        lseek(fd,0,SEEK_SET);
        read(fd, text.data(), length);
        close(fd);
    }
    else {
        perror("read text file error");
    }
#endif
    return text;
}
